
package modele;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import modele.exceptions.MaitreDeStageInexistantException;

/**
 * Class MaitreDeStage permet de représenter un maitre de stage avec le nom
 * de son entreprise.
 */
public class MaitreDeStage extends Personne
{
    private String nomEntreprise;
         
    /**
     * Constructeur avec toutes les informations.
     * L'identifiant est unique pour un intervenant, mais pas par rapport à Personne.
     */
    public MaitreDeStage(int id, String nom, String prenom, String adresse, String mail, String tel, String login, String password, String nomEntreprise){
        super(id, nom, prenom, adresse, mail, tel, login, password);

        this.nomEntreprise = nomEntreprise;

    }

    /**
     * Constructeur partiel de MaitreDeStage, ne doit être utilisé que lorsqu'on n'a
     * pas besoin des autres informations
     */
    public MaitreDeStage(int id, String nom, String prenom, String adresse, String mail, String tel, String nomEntreprise)
    {
        this(id, nom, prenom, adresse, mail, tel, null, null, nomEntreprise);
    }

    /**
     * Constructeur partiel de MaitreDeStage, ne doit être utilisé que lorsqu'on n'a
     * pas besoin des autres informations
     * @param id : identifiant du maitre de stage
     * @param nom : nom du maitre
     * @param prenom : prénom du maitre
     */
    public MaitreDeStage(int id, String nom, String prenom)
    {
        this(id, nom, prenom, null, null, null, null, null, null);
    }

    /**
     * Renvoie le nom de l'entreprise du maitre de stage
     * @return le nom
     */
    public String getNomEntreprise()
    {
        return nomEntreprise;
    }

    /**
     * Met à jour toutes les informations du maitre de stage (en mémoire et en base de données)
     * Il faut aussi modifier la table utilisateur pour le login mot de passe
     */
    public void MAJMaitre(String nom, String prenom, String adresse, String mail, String tel, String login, String password, String nomEntreprise) throws SQLException
    {
        this.setNom(nom);
        this.setPrenom(prenom);
        this.setAdresse(adresse);
        this.setEmail(mail);
        this.setNumTel(tel);
        this.setPassword(password);
        this.nomEntreprise = nomEntreprise;
        
        String requete = "Update maitre_stage set nom = ?, prenom = ?, adresse = ?, email = ?, tel = ?, nom_entreprise = ? where id_ms = ?";
        Connection c = ConnexionBD.getConnection();
        PreparedStatement ps = c.prepareStatement(requete);
        ps.setString(1, nom);
        ps.setString(2, prenom);
        ps.setString(3, adresse);
        ps.setString(4, mail);
        ps.setString(5, tel);
        ps.setString(6, nomEntreprise);
        ps.setInt(7, getId());

        ps.executeUpdate();

        requete = "Update utilisateur set login = ?, password = ? where login = ?";
        ps = c.prepareStatement(requete);
        ps.setString(1, login);
        ps.setString(2, password);
        ps.setString(3, this.getLogin());

        ps.executeUpdate();
        this.setLogin(login);

        c.close();

    }

    /**
     * Supprimer un maitre de stage dont l'identifiant est passé en paramètre.
     * On va d'abord désaffecter le maitre de stage de tous ses étudiants.
     * On va aussi supprimer ses retours sur étudiant.
     * On va aussi supprimer le login et mot de passe
     */
    public static void supprimerMaitre(int id_ms) throws MaitreDeStageInexistantException, SQLException
    {
        MaitreDeStage ms = getMaitreDeStage(id_ms);
        
        String requete = "Update etudiant_session set id_maitrestage = null where id_maitrestage = ?";
        Connection c = ConnexionBD.getConnection();
        PreparedStatement ps = c.prepareStatement(requete);
        ps.setInt(1, id_ms);
        ps.executeUpdate();

        requete = "Delete FROM retour_sur_etudiant WHERE id_ms = ?";
        ps = c.prepareStatement(requete);
        ps.setInt(1, id_ms);
        ps.executeUpdate();

        requete = "Delete FROM maitre_stage WHERE id_ms = ?";
        ps = c.prepareStatement(requete);
        ps.setInt(1, id_ms);
        ps.executeUpdate();

        requete = "Delete FROM utilisateur WHERE login = ?";
        ps = c.prepareStatement(requete);
        ps.setString(1, ms.getLogin());
        ps.executeUpdate();
        
        c.close();
    }

    //Méthodes statiques d'accès à la base de données

     /**
     * Renvoie la liste de tous les maitres de stage
     * @return la liste demandée avec toutes les informations des maitres de stage (sauf login mot de passe)
     */
    public static List<MaitreDeStage> getTousLesMaitresDeStage() throws SQLException
    {
        List<MaitreDeStage> resultat = new ArrayList<MaitreDeStage>();

        String requete = "Select id_ms, prenom, nom, adresse, email, tel, nom_entreprise from maitre_stage order by nom, prenom;";
        Connection c = ConnexionBD.getConnection();
        Statement s = c.createStatement();
        ResultSet rs = s.executeQuery(requete);

        while(rs.next())
        {
            int idms = (Integer) rs.getObject(1);
            String prenom = (String) rs.getObject(2);
            String nom = (String) rs.getObject(3);
            String adresse = (String) rs.getObject(4);
            String email = (String) rs.getObject(5);
            String tel = (String) rs.getObject(6);
            String nomEntreprise = (String) rs.getObject(7);
            MaitreDeStage ms = new MaitreDeStage(idms, nom, prenom, adresse, email, tel, nomEntreprise);

            resultat.add(ms);
        }

        c.close();

        return resultat;
    }

    /**
     * Renvoie la liste des maitres de stage d'une année et d'une formation
     * @param id_annee : l'identifiant de l'année demandée
     * @param id_formation : l'identifiant de la formation demandée
     * @return la liste demandée avec seulement les nom et prénom des maitres de stage
     */
    public static List<MaitreDeStage> getMaitresDeStage(String id_annee, int id_formation) throws SQLException
    {
        List<MaitreDeStage> resultat = new ArrayList<MaitreDeStage>();

        String requete = "Select distinct m.id_ms, m.nom, m.prenom from etudiant e, maitre_stage m where id_annee = ? and id_formation = ? and e.id_maitrestage = m.id_ms order by nom, prenom;";
        Connection c = ConnexionBD.getConnection();
        PreparedStatement ps = c.prepareStatement(requete);
        ps.setString(1, id_annee);
        ps.setInt(2, id_formation);
        ResultSet rs = ps.executeQuery();

        while(rs.next())
        {
            //Pour chaque maitre de stage récupéré

            int id_ms = (Integer) rs.getObject(1);
            String nom = (String) rs.getObject(2);
            String prenom = (String) rs.getObject(3);

            resultat.add(new MaitreDeStage(id_ms, nom, prenom));

        }

        c.close();

        return resultat;
    }

    /**
     * Retourne un maitre de stage dont on a l'identifiant s'il existe, une exception sinon
     * @param id_ms : l'identifiant du maitre de stage
     * @return le maitre de stage demandé
     */
    public static MaitreDeStage getMaitreDeStage(int id_ms) throws MaitreDeStageInexistantException, SQLException
    {
        MaitreDeStage resultat = null;

        String requete = "Select prenom, nom, adresse, email, tel, login, password, nom_entreprise from maitre_stage m, utilisateur u where m.id_ms = ? and u.identifiant = m.id_ms and u.type_utilisateur = 3;";
        Connection c = ConnexionBD.getConnection();
        PreparedStatement ps = c.prepareStatement(requete);
        ps.setInt(1, id_ms);
        ResultSet rs = ps.executeQuery();

        if(rs.next())
        {
            //Le maitre de stage existe
            String prenom = (String) rs.getObject(1);
            String nom = (String) rs.getObject(2);
            String adresse = (String) rs.getObject(3);
            String email = (String) rs.getObject(4);
            String tel = (String) rs.getObject(5);
            String login = (String) rs.getObject(6);
            String password = (String) rs.getObject(7);
            String nomEntreprise = (String) rs.getObject(8);
            resultat = new MaitreDeStage(id_ms, nom, prenom, adresse, email, tel, login, password, nomEntreprise);
        }   
        else
        {
            //Le maitre de stage n'existe pas
            throw new MaitreDeStageInexistantException();
        }

        c.close();

        return resultat;
    }

    /**
     * Initialise et enregistre un nouveau maitre de stage dans la base de données.
     * Si le 'login' a déjà été utilisé, l'enregistrement du nouveau maitre de stage est annulé.
     * @return le maitre qui vient d'être créé et mis en base de données
     */
    public static MaitreDeStage enregistrerNouveauMaitreDeStage(String nom, String prenom, String adresse, String tel, String login, String password, String email, String nomEntreprise) throws SQLException
    {
        MaitreDeStage ms = null;

        String requete = "Insert into maitre_stage(nom, prenom, adresse, tel, email, nom_entreprise) values(?, ?, ?, ?, ?, ?);";
        Connection c = ConnexionBD.getConnection();
        c.setAutoCommit(false);
        PreparedStatement ps = c.prepareStatement(requete);

        try
        {
            ps.setString(1, nom);
            ps.setString(2, prenom);
            ps.setString(3, adresse);
            ps.setString(4, tel);
            ps.setString(5, email);
            ps.setString(6, nomEntreprise);

            ps.executeUpdate();

            //On récupère l'identifiant généré automatiquement de la base de données
            requete = "Select id_ms from maitre_stage where nom = ? and prenom = ? and tel = ?;";
            ps = c.prepareStatement(requete);
            ps.setString(1, nom);
            ps.setString(2, prenom);
            ps.setString(3, tel);
            ResultSet rs = ps.executeQuery();

            rs.next();
            int idms = (Integer) rs.getObject(1);

            requete = "Insert into utilisateur(login, password, type_utilisateur, identifiant) values(?, ?, 3, ?);";
            ps = c.prepareStatement(requete);
            ps.setString(1, login);
            ps.setString(2, password);
            ps.setInt(3, idms);

            ps.executeUpdate();

            ms = new MaitreDeStage(idms, nom, prenom, adresse, email, tel, login, password, nomEntreprise);

            c.commit();
            c.close();
        }
        catch(SQLException e)
        {
            //Si le login existe déjà, on annule tout.
            c.rollback();
            throw new SQLException();
        }

        return ms;
    }
    
    
   


}
